package com.miplus.ccrm.core.service.cust;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJLambdaQueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.CmdResVo;
import com.miplus.ccrm.common.JPubUtils;
import com.miplus.ccrm.common.JSysUser;
import com.miplus.ccrm.common.JUsrPerm;
import com.miplus.ccrm.core.controller.vo.credit.CrdCaseResVo;
import com.miplus.ccrm.core.controller.vo.credit.SysTagsColor;
import com.miplus.ccrm.core.controller.vo.cust.CustReqVo;
import com.miplus.ccrm.core.controller.vo.cust.CustResVo;
import com.miplus.ccrm.core.controller.vo.cust.CustStatisticsResVo;
import com.miplus.ccrm.core.controller.vo.cust.CustTagReqVo;
import com.miplus.ccrm.core.mapper.SysTagsMapper;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.mapper.ConCustomerMapper;
import com.miplus.ccrm.core.utils.EnumRuleStepAction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author pc
* @description 针对表【con_customer(客户表)】的数据库操作Service实现
* @createDate 2024-03-14 11:23:47
*/
@Service
public class ConCustomerServiceImpl extends MPJBaseServiceImpl<ConCustomerMapper, ConCustomer>
    implements ConCustomerService{

    @Resource
    private ConCustomertagService conCustomertagService;

    @Resource
    private SysTagsMapper sysTagsMapper;

    @Resource
    private ConCustomerGrpTagService conCustomerGrpTagService;

    @Override
    public IPage<CustResVo> customerQuery(JSysUser user, CustReqVo paras)
    {
        String $usrid=user.getUsrid();
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        //.apply(!enviewall,"fc_hasCustPurview({0},t.customernumber)>0",$usrid)
        MPJLambdaWrapper<ConCustomer> wrapper = getWrapper(user, paras);
        List<String> selCusts = new ArrayList<>();
        IPage<CustResVo>  custResVoIPage =  selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                CustResVo.class,
                wrapper
//                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
//                        .selectAs("fun_getnames('CUSTOMER.LIST.STATUS',t.list_status)",CustResVo::getListStatusDesc)
//                        .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
//                        .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
//                        .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
//                        .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
//                        .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
//                        .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
//                        .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getType,ConCustomer::getOrigin,ConCustomer::getGender,
                                ConCustomer::getCreatedby,ConCustomer::getCreateddate,ConCustomer::getProvince,ConCustomer::getCity,
                                ConCustomer::getRemark,ConCustomer::getCustname,ConCustomer::getCustenname,ConCustomer::getBirthday,
                                ConCustomer::getCorpname,ConCustomer::getCustemail,ConCustomer::getRisklevel,ConCustomer::getCustacctorgno,
                                ConCustomer::getLastmodifieddate,ConCustomer::getLastmodifiedby,
                                ConCustomer::getPrododudtotalPrin,ConCustomer::getProdmthsStage,ConCustomer::getOverdueDays,
                                ConCustomer::getCpTotalamt,ConCustomer::getRemindRepayPrincipal,ConCustomer::getTotalRepaidAmount,
                                ConCustomer::getRemainingPrincipal,ConCustomer::getOutstandingInterest,ConCustomer::getOverdueProductsC)

        ).convert(x->{
            List<SysTagsColor> custtags=conCustomertagService.selectJoinList(SysTagsColor.class,
                    new MPJLambdaWrapper<>(ConCustomertag.class)
                            .leftJoin(SysTags.class,SysTags::getId,ConCustomertag::getId)
                            .selectAs(ConCustomertag::getId,SysTagsColor::getId)
                            .selectAs(SysTags::getName,SysTagsColor::getDsc)
                            .selectAs(SysTags::getColor,SysTagsColor::getColor)
                            .eq(ConCustomertag::getCustid,x.getCustomernumber())
            );
            x.setTags(custtags);
            selCusts.add(x.getCustomernumber());
            return x;
        });

        if(ObjectUtils.isEmpty(selCusts)){
            return custResVoIPage;
        }
        List<CustResVo> custResVoList = selectJoinList(
                CustResVo.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .selectAs(ConCustomer::getCustomernumber,CustReqVo::getCustomernumber)
                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
                .selectAs("fun_getnames('CUSTOMER.LIST.STATUS',t.list_status)",CustResVo::getListStatusDesc)
                .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
                .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
                .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
                .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
                .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
                .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
                .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .in(ConCustomer::getCustomernumber,selCusts)
        );

        Map<String, CustResVo> custResVoMap = custResVoList.stream().collect(Collectors.toMap(item -> item.getCustomernumber(), item -> item));


        int i = 0;
        while(true)
        {
            CustResVo crdCaseResVo = custResVoMap.get(custResVoIPage.getRecords().get(i).getCustomernumber());
            custResVoIPage.getRecords().get(i).setTypedsc(crdCaseResVo.getTypedsc());
            custResVoIPage.getRecords().get(i).setListStatusDesc(crdCaseResVo.getListStatusDesc());
            custResVoIPage.getRecords().get(i).setOrigindsc(crdCaseResVo.getOrigindsc());
            custResVoIPage.getRecords().get(i).setMarrgstatus(crdCaseResVo.getMarrgstatus());
            custResVoIPage.getRecords().get(i).setHeightedudegr(crdCaseResVo.getHeightedudegr());
            custResVoIPage.getRecords().get(i).setPstn(crdCaseResVo.getPstn());
            custResVoIPage.getRecords().get(i).setOpenacctcerttype(crdCaseResVo.getOpenacctcerttype());
            custResVoIPage.getRecords().get(i).setOpenacctcertno(crdCaseResVo.getOpenacctcertno());

            if( ++i ==  custResVoList.size())
                break;
        }
        return custResVoIPage;

    }


    public  MPJLambdaWrapper getWrapper(JSysUser user, CustReqVo paras){
        boolean enviewall=JUsrPerm.viewAllFiCase(user);
        String $usrid=user.getUsrid();

        String noincludetags=paras.getNoincludetags();
        String tags=JPubUtils.getInString(paras.getTags());

        return new MPJLambdaWrapper<ConCustomer>()
                .exists(!enviewall,String.format("select 1 from fi_creditcases fi where fi.customernumber=t.customernumber and (fi.sendtousr='%s' or fi.sendtodept in(select grm.grpid from sys_grpmgr grm where grm.grpmanagerid='%s'))",$usrid,$usrid))
                .eq(JPubUtils.IsNotEmpty(paras.getCustomernumber()),"customernumber",paras.getCustomernumber())
                .like(JPubUtils.IsNotEmpty(paras.getIdnumber()),"openacctcertno",paras.getIdnumber())
                .eq(JPubUtils.IsNotEmpty(paras.getGender()),"gender",paras.getGender())
                .eq(JPubUtils.IsNotEmpty(paras.getProvince()),"province",paras.getProvince())
                .eq(JPubUtils.IsNotEmpty(paras.getCity()),"city",paras.getCity())
                .eq(JPubUtils.IsNotEmpty(paras.getType()),"type",paras.getType())
                .eq(JPubUtils.IsNotEmpty(paras.getRisklevel()),"risklevel",paras.getRisklevel())
                .eq(JPubUtils.IsNotEmpty(paras.getOrigin()),ConCustomer::getOrigin,paras.getOrigin())
                .likeRight(JPubUtils.IsNotEmpty(paras.getCustname()),"custname",paras.getCustname())
                .between(JPubUtils.IsNotEmpty(paras.getStartdt()), ConCustomer::getCreateddate,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
                .in(JPubUtils.IsNotEmpty(paras.getIdnumberlist()),ConCustomer::getOpenacctcertno,paras.getIdnumberlist())
                .in(JPubUtils.IsNotEmpty(paras.getCustidlist()),ConCustomer::getCustomernumber,paras.getCustidlist())
                .exists("1".equals(noincludetags) && JPubUtils.IsNotEmpty(tags),String.format("select 1 from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s')",tags))
                .notExists("0".equals(noincludetags) && JPubUtils.IsNotEmpty(tags),String.format("select 1 from con_customertag tag where tag.custid=t.customernumber and tag.id in ('%s')",tags))
                .exists(JPubUtils.IsNotEmpty(paras.getPhone()), String.format("select 1 from con_contact ct where ct.customernumber=t.customernumber and ct.phone='%s'",paras.getPhone()));
    }

    @Override
    public CustStatisticsResVo customerQueryStatistics(JSysUser user, CustReqVo paras) {
        MPJLambdaWrapper<ConCustomer> wrapper = getWrapper(user, paras);
        CustStatisticsResVo custStatisticsResVo = selectJoinOne(CustStatisticsResVo.class,
                wrapper.selectSum(ConCustomer::getPrododudtotalPrin, CustStatisticsResVo::getPrododudtotalPrin)
                        .selectSum(ConCustomer::getCpTotalamt, CustStatisticsResVo::getCpTotalamt)
        );
        if(custStatisticsResVo==null){
            return new CustStatisticsResVo();
        }
        if(custStatisticsResVo.getCpTotalamt()!=null){
            custStatisticsResVo.setCpTotalamt(custStatisticsResVo.getCpTotalamt().setScale(2, RoundingMode.HALF_UP));
        }
        if(custStatisticsResVo.getPrododudtotalPrin()!=null){
            custStatisticsResVo.setPrododudtotalPrin(custStatisticsResVo.getPrododudtotalPrin().setScale(2, RoundingMode.HALF_UP));
        }

        return custStatisticsResVo;
    }

    @Override
    public CustResVo customerInfo(JSysUser user,String custid)
    {
        String $usrid=user.getUsrid();
        String idstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        boolean enviewall=JUsrPerm.viewAllFiCase(user);

        CustResVo resVo=selectJoinOne(CustResVo.class,
                new MPJLambdaWrapper<ConCustomer>()
                        .selectAs("fun_getnames('CUST.TYPE',t.type)",CustResVo::getTypedsc)
                        .selectAs("fun_getnames('DATA.ORIGIN',t.origin)",CustResVo::getOrigindsc)
                        .selectAs("fun_getnames('CON.SEX',t.gender)", CustResVo::getGenderdsc)
                        .selectAs("fun_getnames('MARRIAGE.STATUS',t.marrgstatus)",CustResVo::getMarrgstatus)
                        .selectAs("fun_getnames('CON.EDU',t.heightedudegr)", CustResVo::getHeightedudegr)
                        .selectAs("fun_getnames('CON.PSTN',t.pstn)",CustResVo::getPstn)
                        .selectAs("fun_getnames('CON.CERTTYPE',t.openacctcerttype)",CustResVo::getOpenacctcerttype)
                        .selectAs(String.format("fi_starSecu('%s','%s',t.openacctcertno,'%s')",$usrid,JUsrPerm.DISSTAR_IDNO,idstar),CustResVo::getOpenacctcertno)
                        .select(ConCustomer::getCustomernumber,ConCustomer::getType,ConCustomer::getOrigin,ConCustomer::getGender,
                                ConCustomer::getCreatedby,ConCustomer::getCreateddate,ConCustomer::getProvince,ConCustomer::getCity,
                                ConCustomer::getRemark,ConCustomer::getCustname,ConCustomer::getCustenname,ConCustomer::getBirthday,
                                ConCustomer::getCorpname,ConCustomer::getCustemail,ConCustomer::getRisklevel)
                        .apply(!enviewall,"fc_hasCustPurview({0},t.customernumber)>0",$usrid)
                        .eq("customernumber",custid)
                );
        List<SysTagsColor> custtags=conCustomertagService.selectJoinList(SysTagsColor.class,
                new MPJLambdaWrapper<>(ConCustomertag.class)
                        .leftJoin(SysTags.class,SysTags::getId,ConCustomertag::getId)
                        .selectAs(ConCustomertag::getId,SysTagsColor::getId)
                        .selectAs(SysTags::getName,SysTagsColor::getDsc)
                        .selectAs(SysTags::getColor,SysTagsColor::getColor)
                        .eq(ConCustomertag::getCustid,custid)
        );
        resVo.setTags(custtags);

        return resVo;
    }

    @Override
    public CmdResVo updateTags(CustTagReqVo paras)
    {

        if("1".equals(paras.getForceDelete())){
            conCustomertagService.remove(
                    new QueryWrapper<ConCustomertag>()
                            .in("custid",paras.getCustid())
                            .notIn("tid","SYS")
            );
        }

        int ret=0;
        //不要判定上面remove成功与否，失败就异常了，如果没有值，remove会返回false
        if(paras.getTags()!=null && paras.getTags().size()>0){

            for (String custid : paras.getCustid()) {
                List<ConCustomertag> ll=new ArrayList<>();

                if("2".equals(paras.getForceDelete())){
                    conCustomertagService.remove(
                            new QueryWrapper<ConCustomertag>()
                                    .eq("custid",custid)
                                    .in("id",paras.getTags())
                    );
                }

                for (String id : paras.getTags()){
                    SysTags sysTags=sysTagsMapper.tagsSelect(id);
                    if(!JPubUtils.IsEqual(sysTags.getTid(),"SYS")) {
//                        Long count = conCustomertagService.selectJoinCount(new MPJLambdaWrapper<>(ConCustomertag.class)
//                                .eq(ConCustomertag::getCustid, custid)
//                                .eq(ConCustomertag::getId, id)
//                                .eq(ConCustomertag::getTid, sysTags.getTid())
//                        );
//                        if(count == 0){
                            ConCustomertag tag = new ConCustomertag();
                            tag.setId(id);
                            tag.setTid(sysTags.getTid());
                            tag.setCustid(custid);
                            ll.add(tag);
  //                          ret++;
//                        }

                    }
                }

                conCustomertagService.saveBatch(ll);

            }

        }

//        return new CustTagResVo();
        return new CmdResVo(ret,paras.getCustid().get(0));
    }

    @Override
    public int addTag(String custid,String tid,String tagid)
    {
        return addTag(custid,tid,tagid,null);
    }

    @Override
    public int addTag(String custid,String tid,String tagid,String batchid)
    {
        conCustomertagService.remove(
                new QueryWrapper<ConCustomertag>()
                        .eq("custid",custid)
                        .eq("id",tagid)
        );
        //不要判定上面remove成功与否，失败就异常了，如果没有值，remove会返回false
        ConCustomertag tag=new ConCustomertag();
        tag.setCustid(custid);
        tag.setTid(tid);
        tag.setId(tagid);
        tag.setBatchid(batchid);

        int ret=conCustomertagService.getBaseMapper().insert(tag);
        return ret;
    }

    @Override
    public int delTag(String batchid)
    {
        int ret=conCustomertagService.getBaseMapper().delete(
                new QueryWrapper<ConCustomertag>()
                        .eq("batchid",batchid)
        );
        return ret;
    }

    @Override
    public int delTag(String custid,String tagid)
    {
        int ret=conCustomertagService.getBaseMapper().delete(
                new QueryWrapper<ConCustomertag>()
                        .eq("custid",custid)
                        .eq("id",tagid)
        );
        return ret;
    }

    @Override
    public Long checkConditionSql(String sql)
    {
        return baseMapper.checkConditionSql(sql);
    }

    @Override
    @Transactional
    public CmdResVo addCustomerGrpTag(CfgRuleTaskSteps cfgRuleTaskSteps,String sql)
    {
        if(cfgRuleTaskSteps == null ||
                !cfgRuleTaskSteps.getActionCode().equals(EnumRuleStepAction.ADDCUSTTAG.getCode()))
            return new CmdResVo(0,"参数错误");
        if( StringUtils.isEmpty(cfgRuleTaskSteps.getTag() ))
            return new CmdResVo(0,"Tag参数错误");
        //删除标签
//        String sql = cfgRuleTaskSteps.getFilterSql();
//        if(StringUtils.isEmpty(sql))
//            sql = " 1=1 ";
//        //客户黑名单。
//        if( cfgRuleTaskSteps.getExcludeBlack() == 1)
//            sql += " and not exists (select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 1 )";
//
//        if( cfgRuleTaskSteps.getExcludeWhite() == 1)
//            sql += " and not exists ( select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 2 )";
//
//        if( cfgRuleTaskSteps.getExcludeStop() == 1)
//            //sql += " and fi_hasstopcall(fc.creditcaseid,'CASE')=0 ";
//            sql += "  and  not exists( SELECT 1  \n" +
//                    "    FROM fi_stopcall s  \n" +
//                    "    WHERE s.stopkey = fc.creditcaseid and s.stoptype = 'CASE' AND s.status = 2 )";
//        if(cfgRuleTaskSteps.getExcludeCustomerStop() == 1)
//            //sql += " and fi_hasstopcall(cu.customernumber,'CUSTOMER')=0 ";
//            sql += "  and  not exists( SELECT 1  \n" +
//                    "    FROM fi_stopcall s  \n" +
//                    "    WHERE s.stopkey = cu.customernumber and s.stoptype = 'CUSTOMER' AND s.status = 2 )";

        // addtagtype 1：不删除，2：删除当前客户的全部标签，3：删除全部客户的当前标签
        if( ObjectUtils.isNull(cfgRuleTaskSteps.getAddTagType()) ||  cfgRuleTaskSteps.getAddTagType() == 1) {
            //删除 满足条件的所有标签。
            conCustomerGrpTagService.deleteCustomerGrpTag(sql, cfgRuleTaskSteps.getTag());
        }
        else if(cfgRuleTaskSteps.getAddTagType() == 2) {        //删除 满足条件的所有标签。
            conCustomerGrpTagService.deleteCustomerGrpTag(sql,"");
        }
        else if(cfgRuleTaskSteps.getAddTagType() == 3)
        {
            conCustomerGrpTagService.deleteCustomerGrpTag("1=1",cfgRuleTaskSteps.getTag());

        }
        conCustomerGrpTagService.addCustomerGrpTag(sql, cfgRuleTaskSteps.getTag());
        return new CmdResVo(1);
    }
    @Override
    public CmdResVo removeCustomerGrpTag(CfgRuleTaskSteps cfgRuleTaskSteps,String sql)
    {
        if(cfgRuleTaskSteps == null ||
                !cfgRuleTaskSteps.getActionCode().equals(EnumRuleStepAction.DELETECUSTTAG.getCode()))
            return new CmdResVo(0,"参数错误");
        if( StringUtils.isEmpty(cfgRuleTaskSteps.getTag() ))
            return new CmdResVo(0,"Tag参数错误");
        //删除标签
//        String sql = cfgRuleTaskSteps.getFilterSql();
//        if(StringUtils.isEmpty(sql))
//            sql = " 1=1 ";
//        //客户黑名单。
//        if( cfgRuleTaskSteps.getExcludeBlack() == 1)
//            sql += " and not exists (select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 1 )";
//
//        if( cfgRuleTaskSteps.getExcludeWhite() == 1)
//            sql += " and not exists ( select 1 from con_blacklist cbl where cbl.customernumber = cu.customernumber and cbl.type = 2 )";
//
//        if( cfgRuleTaskSteps.getExcludeStop() == 1)
//            //sql += " and fi_hasstopcall(fc.creditcaseid,'CASE')=0 ";
//            sql += "  and  not exists( SELECT 1  \n" +
//                    "    FROM fi_stopcall s  \n" +
//                    "    WHERE s.stopkey = fc.creditcaseid and s.stoptype = 'CASE' AND s.status = 2 )";
//        if(cfgRuleTaskSteps.getExcludeCustomerStop() == 1)
//            //sql += " and fi_hasstopcall(cu.customernumber,'CUSTOMER')=0 ";
//            sql += "  and  not exists( SELECT 1  \n" +
//                    "    FROM fi_stopcall s  \n" +
//                    "    WHERE s.stopkey = cu.customernumber and s.stoptype = 'CUSTOMER' AND s.status = 2 )";

        conCustomerGrpTagService.deleteCustomerGrpTag(sql, cfgRuleTaskSteps.getTag());

        return  new CmdResVo(1);
    }
    @Override
    public CmdResVo addCardScore(CfgRuleTaskSteps cfgRuleTaskSteps, String sql)
    {
        SimpleDateFormat df = new SimpleDateFormat("yyMMddHHmmssSSS");
        String batchid='C'+df.format(new Date());
        Integer count = baseMapper.addCardScore(batchid, cfgRuleTaskSteps.getRuleStepId(), sql);
        return new CmdResVo(count,"创建C卡请求记录成功");
    }
}




